<?php
/**
 * Phpwell Web Client Basic Functional Test
 */

/**
 * Imports
 */
$phpwell_dir = dirname(dirname(dirname(__FILE__)));
require_once(sprintf('%s/%s', $phpwell_dir, 'import.php'));
import_well('test/functional');
import_well('web/client');


/**
 * Test Class
 */
class HttpClientFunctionalCase extends PhpwellFunctionalTestCase {

    var $Browser = NULL;
    var $test_url_f = 'http://localhost/test/http.php?status=%s';

    function startAll() {
        $this->Browser = new HttpClient();
        $this->Browser->error_on_unexpected_code = 0;
    }

    function endAll() {
        $this->Browser = NULL;
    }

    function testInstance() {
        $this->assert($this->is_instance($this->Browser, 'HttpClient'));
    }

    function testGet200() {
        $url = sprintf($this->test_url_f, 200);
        $content = $this->Browser->get($url);

        $this->assert($this->Browser->Response->getStatus() == 200);
        $this->assert($this->Browser->Response->status_code == 2);
        $this->assert($this->contains($content, '<h2>HTTP Status: 200</h2>'));

        #$this->log($content, 1);
    }

    function testGet301() {
        $url = sprintf($this->test_url_f, 301);

        $Browser = new HttpClient();
        $content = $Browser->get($url);

        $this->assert($Browser->Response->status_code == 2);
        $this->assert($Browser->Response->HeaderList['content-type'] == 'text/html');
        $this->assert($Browser->ResponseList[1]['request_url'] ==
                      'http://localhost/test/http.php?status=200');

        #$this->log($Browser->ResponseList);
    }

    function testGet302() {
        $url = sprintf($this->test_url_f, 302);

        $Browser = new HttpClient();
        $content = $Browser->get($url);

        $this->assert($Browser->Response->status_code == 2);
        $this->assert($Browser->Response->HeaderList['content-type'] == 'text/html');
        $this->assert($Browser->ResponseList[1]['request_url'] ==
                      'http://localhost/test/http.php?status=200');

        #$this->log($Browser->ResponseList);
    }

    function testGet301Loop() {
        $url = sprintf($this->test_url_f, 301) . '&loop=1';

        $Browser = new HttpClient();
        $Browser->max_redirects = 3;
        @$content = $Browser->get($url);
        $e = error_get_last();

        $expect_error = 'redirect code 301: redirect limit 3 exceeded';
        $this->assert(strpos($e['message'], $expect_error) !== FALSE);
        $this->assert($Browser->num_redirects == 3);
        $this->assert($Browser->ResponseList[3]['request_url'] ==
                      $Browser->request_url);

        #$this->log($Browser->ResponseList);
    }

    function testGet404() {
        $url = sprintf($this->test_url_f, 404);

        $Browser = new HttpClient();
        @$content = $Browser->get($url);
        $e = error_get_last();

        $expect_error = 'unexpected response code [404]: Not Found';
        $this->assert($this->contains($e['message'], $expect_error));
        $this->assertEqual($Browser->Response->status_code, 4);
        $this->assertEqual($Browser->Response->HeaderList['content-type'], 'text/html');

        #$this->log($Browser->ResponseList);
    }

    function testGet500() {
        $url = sprintf($this->test_url_f, 500);

        $Browser = new HttpClient();
        @$content = $Browser->get($url);
        $e = error_get_last();

        $expect_error = sprintf('unexpected response code [%s]: %s', 500,
                                'Internal Server Error');
        $this->assert($this->contains($e['message'], $expect_error));
        $this->assertEqual($Browser->Response->status_code, 5);
        $this->assertEqual($Browser->Response->HeaderList['content-type'], 'text/html');

        #$this->log($Browser->ResponseList);
    }

    function testPost() {
        $url = sprintf($this->test_url_f, 200);
        $PostDict = array(
            'one' => 1,
            'two' => 'two',
            'three' => base64_encode(serialize(array('a'=>1,'b'=>2,'c'=>3)))
        );
        $expect = <<<XRAW
Array
(
    [one] => 1
    [two] => two
    [three] => YTozOntzOjE6ImEiO2k6MTtzOjE6ImIiO2k6MjtzOjE6ImMiO2k6Mzt9
)
XRAW;

        $Browser = new HttpClient();
        $content = $Browser->post($url, $PostDict);

        $this->assert($Browser->Response->status_code == 2);
        $this->assert($Browser->Response->HeaderList['content-type'] == 'text/html');
        $this->assert($this->contains($content, $expect));

        #$this->log($Browser->ResponseList);
    }

    function testCookies() {
        $url = sprintf($this->test_url_f, 200);
        $PostDict = array(
            'cookie1' => 1,
            'cookie2' => 2,
            'cookie3' => base64_encode(serialize(array('a'=>1,'b'=>2,'c'=>3)))
        );

        $Browser = new HttpClient();
        $content = $Browser->post($url, $PostDict);

        $this->assertEqual($Browser->Response->status_code, 2);
        $this->assertEqual($Browser->Response->HeaderList['content-type'], 'text/html');
        $this->assertEqual($Browser->Response->CookieList[2]['name'], 'cookie3');
        $this->assertEqual($Browser->Response->CookieList[2]['value'],
                           $PostDict['cookie3']);
        $this->assertEqual($Browser->Response->CookieDict['cookie3'],
                           $PostDict['cookie3']);

        $this->log($Browser->Response->CookieDict);
    }

    function testW3Redirect() {
        $url = 'http://jigsaw.w3.org/HTTP/300/302.html';
        $Browser = new HttpClient();
        $content = $Browser->get($url);

        $this->assert($Browser->Response->status_code == 2);
        $this->assert($Browser->Response->HeaderList['content-type'] == 'text/html');
        $this->assert($Browser->ResponseList[1]['request_url'] ==
                      'http://jigsaw.w3.org/HTTP/300/Overview.html');
    }
}

$Test = &new HttpClientFunctionalCase();
$Test->run();
print $Test->report();
